#include "Thread.hpp"

namespace xkk
{

namespace current_thread
{
__thread const char* name="xkk thread";
}

struct ThreadData
{
    using ThreadCallback=std::function<void()>;

    ThreadData(const string &name,const ThreadCallback &cb)
        :_name(name)
         ,_cb(cb)
    {}

    void runInThread()
    {
        current_thread::name=(_name==string()?"xkk thread":_name.c_str());
        if(_cb)
            _cb();
    }

    string _name;
    ThreadCallback _cb;
};
Thread::Thread(ThreadCallback && cb,const string &name)
:_pthid(0)
    ,_name(name)
    ,_cb(std::move(cb))
    ,_isRunning(false)
{}

Thread::~Thread()
{
    if(_isRunning){
        pthread_detach(_pthid);
        _isRunning=false;
    }
}

void Thread::start()
{
    ThreadData* pdata=new ThreadData(_name,_cb);
    pthread_create(&_pthid,nullptr,threadFunc,pdata);
    _isRunning=true;
}

void *Thread::threadFunc(void *arg)
{
    ThreadData* pdata=static_cast<ThreadData*>(arg);
    if(pdata){
        pdata->runInThread();
    }
    delete pdata;
    return nullptr;
}

void Thread::join()
{
    if(_isRunning){
        pthread_join(_pthid,nullptr);
        _isRunning=false;
    }
}

}//end of namespace xkk
